#pragma once
#define oneLength 5	//Number to increment 
#define GUI_INTEGRATED
#ifdef	GUI_INTEGRATED	
#include "BaseObject.h"	
#endif
#ifndef GUI_INTEGRATED
struct point
{
	int x, y;
	point(): x(0), y(0){}
	point(int x, int y): x(x), y(y){}
};

class BaseObject
{
protected:
	point m_pLocation;								// two-dimensional location in world space
	int m_iType;									// the type of object to be set by derived objects
	bool m_bActive;
public:

	inline int		getType()	{return m_iType; }
	inline point	getLoc()	{return m_pLocation; }

	virtual void Init(point loc, int type) = 0;
};

#endif
#ifndef NULL
#define NULL 0
#endif

struct Quad
{
	int x,y,width,height;
	Quad():x(0),y(0),width(0),height(0){};
	Quad(int x,int y,int Width,int Height)
		:x(x),y(y),width(Width),height(Height){};
	inline int getMinY()const{return y;}
	inline int getMinX()const{return x;}
	inline int getMaxY()const{return y+height;}
	inline int getMaxX()const{return x+width;}
	bool isColliding(Quad const & q)
	{
		return 
		 !( getMinY() > q.getMaxY()	// this is below q
		 || getMaxY() < q.getMinY() // this is above q
		 || getMinX() > q.getMaxX()	// this is right of q
		 || getMaxX() < q.getMinX());// this is left of q
	}
};
struct TextBox
{
	char*	val;
	Quad	pos;
	TextBox() :val(""),pos(Quad(0,0,0,0)){};
	TextBox(char* Value,Quad Position)
		:val(Value),pos(Position){};
	bool operator== (TextBox toCheck) 
	{
		if(toCheck.pos.x == this->pos.x)
			if(toCheck.pos.y == this->pos.y)
				if(toCheck.pos.height == this->pos.width)
					if(toCheck.pos.width == this->pos.width)
						if(toCheck.val == this->val)
							return true;
		return false;
	}

};

#define MORPH_NULL    0
#define MORPH_BUTTON  1
#define MORPH_PANEL	  2

class gui_morph : public BaseObject
{
private:
	int Morph;	//What manner of object this is
	void Init(point Pos, int ID);

protected:

	Quad	m_qBound;	

	bool	(*ShowFunction)();	//Determines whether the Morph is Active.
	void	(*ExecuteFunct)();	//Determines what the morph should do.

	//For Textboxes
	int			m_iElements;		//Number of elements to write
	int			m_iAllocatedSpace;	//How many spaces we've allocated
	TextBox*	m_tbTexts;			//All the values to be written

public:
	gui_morph(){Morph = MORPH_NULL;};

	//===Mutators
	void InitAsMenu		(int ID, bool(*check)(),Quad Bound);
	void InitAsButton	(int ID, bool(*check)(),Quad Bound,void (*execute)());
	//InitAsMenuCluster
	//InitAsDock
	//InitAsDockAble
	//Todo: Implement movability
	void addTextBox		(Quad Pos, char* Value);
	void update();
	//===Accessors
	bool	checkCollision(point Loc);
	TextBox access(int Index);

};

//Todo: Fix the bounding box stuff